package com.xbongbong.crm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.help.FineClueHelp;
import com.xbongbong.crm.help.SearchCustomerHelp;
import com.xbongbong.crm.service.SearchCustomerService;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.BusinessFieldPojo;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.model.FineClueCompanyModel;
import com.xbongbong.paas.model.FineClueUserModel;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.SearchCustomerCompanyModel;
import com.xbongbong.paas.model.SearchCustomerUserModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.constant.SoukeUrlConstant;
import com.xbongbong.pro.domain.entity.FineClueCompanyEntity;
import com.xbongbong.pro.domain.entity.FineClueUserEntity;
import com.xbongbong.pro.domain.entity.SearchCustomerCompanyEntity;
import com.xbongbong.pro.domain.entity.SearchCustomerTemplateEntity;
import com.xbongbong.pro.domain.entity.SearchCustomerUserEntity;
import com.xbongbong.pro.enums.BusinessSearchEnum;
import com.xbongbong.pro.enums.ClueDetailJoinEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.FineClueEnum;
import com.xbongbong.pro.enums.SearchCustomerEnum;
import com.xbongbong.pro.enums.SoukeMealEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.SearchCustomerErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.searchcustomer.pojo.SearchCustomerFieldPojo;
import com.xbongbong.pro.searchcustomer.pojo.SearchCustomerTemplatePojo;
import com.xbongbong.pro.searchcustomer.pojo.dto.Clue;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerAdminDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerCallbackDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerStaffDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerTemplateDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchCustomerUserDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.SearchEnterpriseDTO;
import com.xbongbong.pro.searchcustomer.pojo.dto.TargetDTO;
import com.xbongbong.pro.searchcustomer.pojo.vo.JumpClueDetailVO;
import com.xbongbong.pro.searchcustomer.pojo.vo.SearchCustomerDataVO;
import com.xbongbong.pro.searchcustomer.pojo.vo.SearchCustomerMealVO;
import com.xbongbong.pro.searchcustomer.pojo.vo.SearchCustomerMsgVO;
import com.xbongbong.pro.searchcustomer.pojo.vo.SearchCustomerTemplateVO;
import com.xbongbong.pro.searchcustomer.pojo.vo.SearchCustomerUserListVO;
import com.xbongbong.pro.searchcustomer.pojo.vo.SearchCustomerUserVO;
import com.xbongbong.pro.searchcustomer.pojo.vo.SearchCustomerVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;

/**
 * @Author shian
 * @create 2019-07-31 18:55
 * @Description
 */
@Service("searchCustomerService")
public class SearchCustomerServiceImpl implements SearchCustomerService {

    private static final Logger LOG = LoggerFactory.getLogger(SearchCustomerServiceImpl.class);

    /**
     * 企业基本信息
     */
    private static final String INFORMATION = "Information";

    /**
     * 企业年报
     */
    private static final String REPORT = "Report";

    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private SearchCustomerHelp searchCustomerHelp;
    @Resource
    private SearchCustomerUserModel searchCustomerUserModel;
    @Resource
    private SearchCustomerCompanyModel searchCustomerCompanyModel;
    @Resource
    private UserModel userModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FineClueCompanyModel fineClueCompanyModel;
    @Resource
    private FineClueHelp fineClueHelp;
    @Resource
    private FineClueUserModel fineClueUserModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Override
    public JSONObject sendRegister(SearchCustomerDTO searchCustomerDTO ) throws XbbException{

        JSONObject jsonObject;
        try {
            UUID uuid = UUID.randomUUID();
            String key = uuid.toString();
            String json = JSONObject.toJSONString(searchCustomerDTO);

            Map<String, String> map =new HashMap<>(16);
            map.put("user_token", key);

            String value = paasRedisHelper.getValue(RedisPrefixConstant.SEARCHCUSTOMER_OPEN_TIME, key);
            if(StringUtil.isEmpty(value) || !Objects.equals(json, value)){
                // 有效期为1分钟
                paasRedisHelper.setValue(RedisPrefixConstant.SEARCHCUSTOMER_OPEN_TIME, key, json,60);
            }
            // 发送post请求调用搜客注册接口
            jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.SEND_REGISTER_URL, map, HttpMethod.POST, SoukeMealEnum.SOUKE);

        } catch (XbbException e) {
            LOG.error("注册失败：" + e.getMessage());
            throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401017);
        }

        return jsonObject;
    }

    @Override
    public SearchCustomerVO getCustomerInfo(@Valid SearchCustomerCallbackDTO searchCustomerCallbackDTO) throws XbbException{
        SearchCustomerVO searchCustomerVO = new SearchCustomerVO();
        String token = searchCustomerCallbackDTO.getUser_token();
        String value = paasRedisHelper.getValue(RedisPrefixConstant.SEARCHCUSTOMER_OPEN_TIME, token);

        if(StringUtil.isEmpty(value)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018, "注册失败");
        }
        SearchCustomerDTO searchCustomerDTO = JSONObject.parseObject(value, SearchCustomerDTO.class);

        LOG.info("注册---" + searchCustomerDTO.toString());

        searchCustomerVO.setError_code(0);
        searchCustomerVO.setSuccess(true);
        searchCustomerVO.setMessage("");

        searchCustomerVO.setData((JSONObject) JSON.toJSON(searchCustomerDTO));
        return searchCustomerVO;
    }


    @Override
    public SearchCustomerVO loginSearchCustomer(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException {

        SearchCustomerVO searchCustomerVO = new SearchCustomerVO();

        Map<String ,String> map = new HashMap<>(4);
        map.put("uid", searchCustomerDTO.getUid());
        JSONObject jsonObject;
        int errorCode;
        try {
            // 判断登录的用户是否是主账号
            SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(searchCustomerDTO.getCorpid(), SoukeMealEnum.SOUKE.getType());
            if (soukeEntity != null && soukeEntity.getExtraExpiry() > DateUtil.getInt()) {
                if (Objects.equals(searchCustomerDTO.getUserId(), soukeEntity.getUserId())) {
                    map.put("uid", soukeEntity.getUid());
                }
                // 开通试用搜客，所有员工都可登录
                if (soukeEntity.getExtraExpiry() - soukeEntity.getAddTime() < 4 * RedisConstant.LONG_DURATION) {
                    map.put("uid", soukeEntity.getUid());
                }

                //如果该用户无token，则请求接口获取
                SearchCustomerUserEntity soukeUserEntity = searchCustomerUserModel.getByKey(searchCustomerDTO.getUserId(), searchCustomerDTO.getCorpid());
                if (Objects.isNull(soukeUserEntity) || StringUtil.isEmpty(soukeUserEntity.getToken())) {
                    if (StringUtils.isNotEmpty(searchCustomerDTO.getGuest())) {
                        map.put("guest", searchCustomerDTO.getGuest());
                    }
                    jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.LOGIN_SOUKE_URL, map, HttpMethod.POST, SoukeMealEnum.SOUKE);
                    if (Objects.isNull(jsonObject)) {
                        throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401016);
                    }
                    errorCode = jsonObject.getInteger("error_code");
                    if (errorCode != 0) {
                        throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401016);
                    }
                    JSONObject data = jsonObject.getJSONObject("data");
                    if (Objects.nonNull(soukeUserEntity)) {
                        String token = data.getString("token");
                        soukeUserEntity.setToken(token);
                        searchCustomerUserModel.save(soukeUserEntity);
                    }
                    searchCustomerVO.setError_code(errorCode);
                    searchCustomerVO.setSuccess(jsonObject.getBoolean("success"));
                    searchCustomerVO.setMessage(jsonObject.getString("message"));
                    searchCustomerVO.setData(data);
                } else {
                    JSONObject data = new JSONObject();
                    data.put("token", soukeUserEntity.getToken());
                    searchCustomerVO.setError_code(0);
                    searchCustomerVO.setData(data);
                }
            } else {
                // 工商的登录
                jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.LOGIN_SOUKE_URL, map, HttpMethod.POST, SoukeMealEnum.SOUKE);
                if (Objects.isNull(jsonObject)) {
                    throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401016);
                }
                errorCode = jsonObject.getInteger("error_code");
                if (errorCode != 0){
                    throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401016);
                }
                JSONObject data = jsonObject.getJSONObject("data");
                searchCustomerVO.setError_code(errorCode);
                searchCustomerVO.setSuccess(jsonObject.getBoolean("success"));
                searchCustomerVO.setMessage(jsonObject.getString("message"));
                searchCustomerVO.setData(data);
            }
            LOG.info("客户登录token信息 =" + searchCustomerVO.getData());
        } catch (XbbException e) {
            LOG.error("登录失败：" + e.getMessage());
        }
        return searchCustomerVO;
    }

    @Override
    public SearchCustomerVO notifyInfo(@Valid SearchCustomerCallbackDTO searchCustomerCallbackDTO, @Valid TargetDTO targetDTO) throws XbbException{
        SearchCustomerVO searchCustomerVO = new SearchCustomerVO();
        JSONObject data = new JSONObject();
        Map<String, Object> map = new HashMap<>(16);

        String str = JSONObject.toJSONString(searchCustomerCallbackDTO);
        String target = targetDTO.getTarget();
        String key = searchCustomerCallbackDTO.getUid();
        map.put("data", str);
        map.put("target",target);
        if (StringUtil.isEmpty(target)) {
            searchCustomerVO.setData(data);
            return searchCustomerVO;
        }
        String value = paasRedisHelper.getValue(RedisPrefixConstant.CLUE_TO_CUSTOMER, key);
        LOG.info("搜客转客户数据 = " + value);
        LOG.info("-----------搜客的数据 =" + str);
        if(StringUtil.isEmpty(value) || !Objects.equals(JSON.toJSONString(map), value)){
            LOG.info("写入redis");
            // 有效期为10分钟
            paasRedisHelper.setValue(RedisPrefixConstant.CLUE_TO_CUSTOMER, key, map,600);
        }
        searchCustomerVO.setError_code(0);
        searchCustomerVO.setSuccess(true);
        List<Clue> clues = searchCustomerCallbackDTO.getClues();
        if (CollectionUtils.isNotEmpty(clues)){
            clues.forEach(item-> data.put(item.getClueId(), ""));
        }

        searchCustomerVO.setData(data);
        return searchCustomerVO;
    }

    @Override
    public SearchCustomerDataVO notice(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException {
        SearchCustomerDataVO searchCustomerDataVO = new SearchCustomerDataVO();
        String uid = searchCustomerDTO.getUid();
        // 判断登录的用户是否是主账号
        SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(searchCustomerDTO.getCorpid(), SoukeMealEnum.SOUKE.getType());
        if (soukeEntity != null && Objects.equals(searchCustomerDTO.getUserId(), soukeEntity.getUserId())){
            uid = soukeEntity.getUid();
        }
        // 开通试用搜客，所有员工都可登录
        if (soukeEntity != null && soukeEntity.getExtraExpiry() - soukeEntity.getAddTime() < 4 * RedisConstant.LONG_DURATION
                && soukeEntity.getExtraExpiry() > DateUtil.getInt()) {
            uid = soukeEntity.getUid();
        }
        // 获取缓存中的数据
        String value = paasRedisHelper.getValue(RedisPrefixConstant.CLUE_TO_CUSTOMER, uid);
        LOG.info("搜客转客户数据 = " + value);
        if (StringUtil.isEmpty(value)) {
            throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401015);
        }
        Map map = JSONObject.parseObject(value, Map.class);
        searchCustomerDataVO.setData((String) map.get("data"));
        searchCustomerDataVO.setTarget((String) map.get("target"));
        return searchCustomerDataVO;
    }


    @Override
    public JSONObject bind(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException {
        JSONObject jsonObject = null;
        try {
            Map<String, String> map =new HashMap<>(16);
            map.put("uid", searchCustomerDTO.getUid());
            map.put("user_id", searchCustomerDTO.getUser_id());
            // 发送put请求调用搜客绑定用户接口
            jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.BIND_SOUKE_URL, map, HttpMethod.PUT, SoukeMealEnum.SOUKE);

        } catch (XbbException e) {
            LOG.error("绑定用户失败：" + e.getMessage());
        }
        return jsonObject;
    }

    @Override
    public JSONObject meal(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException {
        JSONObject jsonObject = null;
        try {
            Map<String, Object> map = new HashMap<>(16);
            map.put("uid", searchCustomerDTO.getUid());
            map.put("type", searchCustomerDTO.getType());
            map.put("mealType", searchCustomerDTO.getMealType());
            map.put("extraSubCount", searchCustomerDTO.getExtraSubCount());
            map.put("expiry_num", searchCustomerDTO.getExpiry_num());

            jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.MEAL_SOUKE_URL, map, HttpMethod.PATCH, SoukeMealEnum.SOUKE);

        } catch (XbbException e) {
            LOG.error("升级或续费套餐失败：" + e.getMessage());
        }
        return jsonObject;
    }

    @Override
    public JSONObject unbind(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException {
        JSONObject jsonObject = null;
        try {
            Map<String, String> map =new HashMap<>(16);
            map.put("uid", searchCustomerDTO.getUid());
            map.put("user_id", searchCustomerDTO.getUser_id());

            jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.UNBIND_SOUKE_URL, map, HttpMethod.PUT, SoukeMealEnum.SOUKE);

        } catch (XbbException e) {
            LOG.error("解绑用户失败：" + e.getMessage());
        }
        return jsonObject;
    }

    @Override
    public JSONObject info(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException {
        JSONObject jsonObject = new JSONObject();
        String corpid = searchCustomerDTO.getCorpid();
        String userId = searchCustomerDTO.getUserId();
        FineClueCompanyEntity companyEntity = fineClueCompanyModel.getByCorpid(corpid, FineClueEnum.FINE_CLUE.getType());
        PaasAppEntity appEntity = paasAppModel.getByAlias(ProPermissionAliasEnum.SOUKE.getAlias(), corpid);
        fineClueCompanyModel.getByCorpid(corpid, FineClueEnum.FINE_CLUE.getType());
        FineClueUserEntity clueUserEntity = fineClueUserModel.getByKey(corpid, userId);
        //有坐席，搜客没过期，应用开启->显示
        if ((Objects.nonNull(companyEntity) && Objects.nonNull(clueUserEntity) && fineClueHelp.fineClueUsable(corpid, FineClueEnum.FINE_CLUE)) && (Objects.nonNull(appEntity) && Objects.equals(appEntity.getEnable(), BasicConstant.ONE))){
            FineClueUserEntity userEntity = fineClueUserModel.getByKey(corpid, userId);
            if (Objects.nonNull(userEntity)){
                Integer type = userEntity.getClueUseType();
                Integer clueUseNum = userEntity.getClueUseNum();
                JSONObject data = new JSONObject();
                int surplusNum = fineClueHelp.getUseNumber(corpid, userId, type);
                data.put("type",type);
                data.put("view_contact_num_left",surplusNum);
                data.put("view_contact_num",clueUseNum);
                jsonObject.put(StringConstant.JSON_DATA,data);
                return jsonObject;
            }
        }
        try {
            String uid = searchCustomerDTO.getUid();
            // 判断登录的用户是否是主账号
            SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(searchCustomerDTO.getCorpid(), SoukeMealEnum.SOUKE.getType());
            if (soukeEntity != null && Objects.equals(searchCustomerDTO.getUserId(), soukeEntity.getUserId())){
               uid = soukeEntity.getUid();
            }
            // 开通试用搜客，所有员工都可登录
            if (soukeEntity != null && soukeEntity.getExtraExpiry() - soukeEntity.getAddTime() < 4 * RedisConstant.LONG_DURATION
                    && soukeEntity.getExtraExpiry() > DateUtil.getInt()) {
                uid = soukeEntity.getUid();
            }
            String url = SoukeUrlConstant.STATUS_USER_URL + uid;
            jsonObject = searchCustomerHelp.httpExchange(url, "", HttpMethod.GET, SoukeMealEnum.SOUKE);
        } catch (XbbException e) {
            LOG.error("查看主/子账户信息失败：" + e.getMessage());
        }
        return jsonObject;
    }

    @Override
    public JSONObject userPackage(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException {
        JSONObject jsonObject = null;
        try {
            String uid = searchCustomerDTO.getUid();
            String url = SoukeUrlConstant.PACKAGE_USER_URL + uid;
            LOG.info("查询（主/子）账号套餐url=====" + url);
            jsonObject = searchCustomerHelp.httpExchange(url, "", HttpMethod.GET, SoukeMealEnum.SOUKE);

        } catch (XbbException e) {
            LOG.error("查看主/子账户套餐失败：" + e.getMessage());
        }
        return jsonObject;
    }

    @Override
    public JSONObject enable(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException{
        JSONObject jsonObject = null;
        try {
            Map<String, Object> map =new HashMap<>(16);
            map.put("uid", searchCustomerDTO.getUid());
            map.put("enable", searchCustomerDTO.getEnable());

            jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.ENABLE_SOUKE_URL, map, HttpMethod.PUT, SoukeMealEnum.SOUKE);

        } catch (XbbException e) {
            LOG.error("禁用或者启用用户失败：" + e.getMessage());
        }
        return jsonObject;
    }

    @Override
    public JSONObject disuser(@Valid SearchCustomerDTO searchCustomerDTO) throws XbbException{
        JSONObject jsonObject = null;
        try {
            String uid = searchCustomerDTO.getUid();

            jsonObject = searchCustomerHelp.httpExchange(SoukeUrlConstant.DISUSER_SOUKE_URL, uid, HttpMethod.DELETE, SoukeMealEnum.SOUKE);

        } catch (XbbException e) {
            LOG.error("注销用户失败：" + e.getMessage());
        }
        return jsonObject;
    }
    @Override
    public SearchCustomerTemplateVO useTemplate(@Valid SearchCustomerTemplateDTO searchCustomerTemplateDTO) throws XbbException {
        SearchCustomerTemplateVO searchCustomerTemplateVO = new SearchCustomerTemplateVO();

        SearchCustomerTemplateEntity searchCustomerTemplateEntity = searchCustomerHelp.getInitTemplate();

        String data = searchCustomerTemplateEntity.getData();
        List<SearchCustomerFieldPojo> fieldPojos = JSONArray.parseArray(data, SearchCustomerFieldPojo.class);
        Map<String, SearchCustomerFieldPojo> fieldPojoMap = new HashMap<>(16);
        fieldPojos.forEach(item-> fieldPojoMap.put(item.getAttr(), item));

        List<SearchCustomerEnum> searchCustomerEnumList = SearchCustomerEnum.getAllEnum();
        List<SearchCustomerTemplatePojo> explainList = new ArrayList<>();


        searchCustomerEnumList.forEach(item->{
            SearchCustomerTemplatePojo pojo = new SearchCustomerTemplatePojo();
            String attr = item.getAttr();
            pojo.setAttr(attr);
            pojo.setAttrName(item.getAttrName());
            pojo.setItem(fieldPojoMap.get(attr));

            explainList.add(pojo);
        });

        searchCustomerTemplateVO.setExplainList(explainList);
        return searchCustomerTemplateVO;
    }

    @Override
    public SearchCustomerTemplateVO saveTemplate(@Valid SearchCustomerTemplateDTO searchCustomerTemplateDTO) throws XbbException {
        SearchCustomerTemplateVO searchCustomerTemplateVO = new SearchCustomerTemplateVO();
        SearchCustomerTemplateEntity templateEntity = new SearchCustomerTemplateEntity();
        BeanUtil.copyProperties(searchCustomerTemplateDTO, templateEntity);
        // 后期处理
        return searchCustomerTemplateVO;
    }

    @Override
    public SearchCustomerUserListVO getDepUserList(@Valid SearchCustomerUserDTO searchCustomerUserDTO) throws XbbException {
        SearchCustomerUserListVO searchCustomerUserListVO = new SearchCustomerUserListVO();
        String corpid = searchCustomerUserDTO.getCorpid();
        Long deptId = searchCustomerUserDTO.getDepId();

        List<SearchCustomerUserVO> userVOList = new ArrayList<>();
        try {
            Map<String, Object> userParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            userParam.put(StringConstant.CORPID, corpid);
            userParam.put("departmentId", deptId);
            userParam.put("page", searchCustomerUserDTO.getPage());
            userParam.put("nameLike", searchCustomerUserDTO.getNameLike());
            //对departmentId 为 1 （全公司）做特殊处理
            if (deptId != null && deptId.equals(PaasConstant.CORP_DEPARTMENT_ID)) {
                userParam.remove("departmentId");
            }
            PageHelper pageHelper = PageHelperUtil.getPageHelper(userParam, userModel, searchCustomerUserDTO.getPageSize());
            List<UserEntity> list = (List<UserEntity>) PageHelperUtil.getEntityList(userParam, pageHelper, userModel);
            List<UserVO> userList = new ArrayList<>();
            BeanUtil.copyPropertiesList(list, userList, UserVO.class);

            Set<String> userIdIn = new HashSet<>();
            userList.forEach(item -> userIdIn.add(item.getUserId()));
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid",corpid);
            param.put("userIdIn", userIdIn);
            param.put("del", DelEnum.NORMAL.getDel());
            List<SearchCustomerUserEntity> searchCustomerUserList = searchCustomerUserModel.findEntitys(param);

            Map<String, SearchCustomerUserEntity> userEntityMap = new HashMap<>(searchCustomerUserList.size());
            searchCustomerUserList.forEach((item)-> userEntityMap.put(item.getUserId(), item));
            userList.forEach(item -> {
                String userId = item.getUserId();
                SearchCustomerUserVO searchCustomerUserVO = new SearchCustomerUserVO();
                BeanUtil.copyProperties(item, searchCustomerUserVO);
                SearchCustomerUserEntity entity = userEntityMap.get(userId);
                if (entity != null){
                    searchCustomerUserVO.setStaff(entity.getStaff());
                    searchCustomerUserVO.setAdmin(entity.getAdmin());
                } else {
                    searchCustomerUserVO.setStaff(0);
                    searchCustomerUserVO.setAdmin(0);
                }
                userVOList.add(searchCustomerUserVO);
            });

            searchCustomerUserListVO.setPageHelper(pageHelper);
            searchCustomerUserListVO.setUserList(userVOList);
        } catch (XbbException e) {
           LOG.error("获取部门信息失败" + e.getMessage());
        } catch (Exception e) {
            LOG.error("获取部门信息失败" + e.getMessage());
        }

        return searchCustomerUserListVO;
    }

    @Override
    public SearchCustomerMealVO getCompanyMeal(@Valid SearchCustomerUserDTO searchCustomerUserDTO) throws XbbException {
        SearchCustomerMealVO searchCustomerMealVO = new SearchCustomerMealVO();
        String corpid = searchCustomerUserDTO.getCorpid();

        SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.SOUKE.getType());

        if(soukeEntity == null){
            throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401012);
        }
        // 查看该公司已使用搜客的人数
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("staff", 1);
        param.put("del", DelEnum.NORMAL.getDel());
        // 正在使用搜客的人数
        int count = searchCustomerUserModel.getEntitysCount(param);

        searchCustomerMealVO.setUseAmount(count);
        searchCustomerMealVO.setTotalAmount(soukeEntity.getUseCount());
        searchCustomerMealVO.setEndTime(soukeEntity.getExtraExpiry());
        return searchCustomerMealVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SearchCustomerMsgVO updateAdmin(@Valid SearchCustomerAdminDTO searchCustomerAdminDTO) throws XbbException {
        SearchCustomerMsgVO searchCustomerMsgVO = new SearchCustomerMsgVO();

        int admin = searchCustomerAdminDTO.getAdmin();
        String corpid = searchCustomerAdminDTO.getCorpid();
        String userId = searchCustomerAdminDTO.getUserId();
        String allowUserId = searchCustomerAdminDTO.getAllowUserId();
        long now = DateUtil.getInt();

        UserEntity userEntity = userModel.getByKey(allowUserId, corpid);
        if (userEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004);
        }
        UserVO loginUser = searchCustomerAdminDTO.getLoginUser();
        Set<String> permSet = loginUser.getPermSet();
        if (!permSet.contains(ProPermissionAliasEnum.SOUKE_EDIT.getAlias())){
            throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401003);
        }
        if (Objects.equals(userId, allowUserId)) {
            throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401009);
        }

        /**
         * 主账户更换逻辑：tb_search_customer_company中user_id与username的改变
         * 1、主账户A->B （B为坐席）：A的admin=0，staff=0，isBind=0，A的clue_user_id与B的clue_user_id交换，B做解绑操作，B的admin=1
         * 2、主账户A->B （B不是坐席且不是初始化主账户）：A的admin=0，staff=0，A的clue_user_id置为空，新增B数据或者更新B
         * 3、主账户A->B （B为初始化主账户）：B不是坐席（因为初始化主账户被移交主账户后，不能给它设置坐席），
         *       A的admin=0，staff=0，A的clue_user_id与B的clue_user_id交换，B的admin=1
         */
        if (admin == 1) {
            SearchCustomerUserEntity entity = searchCustomerUserModel.getByKey(allowUserId, corpid);
            SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.SOUKE.getType());

            SearchCustomerUserEntity oldAdminEntity = searchCustomerUserModel.getByKey(soukeEntity.getUserId(), corpid);
            // 原主账户（A）与需设置的用户（B）的clue_user_id互换
            String adminClueUserId = oldAdminEntity.getClueUserId();
            String simpleClueUserId = "";
            if (entity == null) {
                entity = new SearchCustomerUserEntity();
                entity.setCorpid(corpid);
                entity.setUserId(allowUserId);
                entity.setClueUserId(adminClueUserId);
                entity.setAdmin(admin);
                entity.setStaff(1);
                entity.setIsBind(0);
                entity.setDel(0);
                searchCustomerUserModel.insert(entity);
            } else {
                simpleClueUserId = entity.getClueUserId();
                if (!Objects.equals(soukeEntity.getUid(), corpid + allowUserId) && entity.getStaff() == 1) {
                    // B做解绑操作，防止主账户切换依然占搜客一个坐席
                    SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(corpid + allowUserId);
                    searchCustomerDTO.setUser_id(simpleClueUserId);
                    JSONObject data = unbind(searchCustomerDTO);
                    LOG.info("=====取消坐席时解绑=======" + data);
                    if (data == null || (int) data.get("error_code") != 0) {
                        searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401005.getCode());
                        searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401005.getMsg());
                        return searchCustomerMsgVO;
                    }
                }
                entity.setClueUserId(adminClueUserId);
                entity.setAdmin(admin);
                entity.setStaff(1);
                entity.setToken("");
                entity.setUpdateTime(now);
                searchCustomerUserModel.update(entity);
            }
            oldAdminEntity.setClueUserId(simpleClueUserId);
            oldAdminEntity.setAdmin(0);
            oldAdminEntity.setStaff(0);
            oldAdminEntity.setToken("");
            searchCustomerUserModel.update(oldAdminEntity);

            soukeEntity.setUserId(allowUserId);
            soukeEntity.setUsername(userEntity.getName());
            searchCustomerCompanyModel.update(soukeEntity);
        } else if (admin == 0){
            searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401014.getCode());
            searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401014.getMsg());
            return searchCustomerMsgVO;
        }

        searchCustomerMsgVO.setCode(ErrorCodeEnum.API_SUCCESS.getCode());
        searchCustomerMsgVO.setMsg(ErrorCodeEnum.API_SUCCESS.getMsg());
        return searchCustomerMsgVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SearchCustomerMsgVO updateStaff(@Valid SearchCustomerStaffDTO searchCustomerStaffDTO) throws XbbException {
        SearchCustomerMsgVO searchCustomerMsgVO = new SearchCustomerMsgVO();
        try {
            int staff = searchCustomerStaffDTO.getStaff();
            String corpid = searchCustomerStaffDTO.getCorpid();
            String userId = searchCustomerStaffDTO.getUserId();
            String allowUserId = searchCustomerStaffDTO.getAllowUserId();
            String uid = corpid + allowUserId;

            UserEntity userEntity = userModel.getByKey(userId, corpid);
            if (userEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004);
            }
            UserVO loginUser = searchCustomerStaffDTO.getLoginUser();
            Set<String> permSet = loginUser.getPermSet();
            if (!permSet.contains(ProPermissionAliasEnum.SOUKE_EDIT.getAlias())){
                throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401003);
            }
            UserEntity allowUserEntity = userModel.getByKey(allowUserId, corpid);
            SearchCustomerUserEntity entity = searchCustomerUserModel.getByKey(allowUserId, corpid);

            // 搜客只有一个主账户，多个子账户(只有主账户才能设置子账户)，解决搜客管理员（N人）设置员工的方法：找到该公司的搜客主账户来设置子账户
            SearchCustomerCompanyEntity soukeCompanyEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.SOUKE.getType());
            userId = soukeCompanyEntity.getUserId();

            if (Objects.equals(userId, allowUserId)) {
                throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401010);
            }
            if (Objects.equals(corpid + allowUserId, soukeCompanyEntity.getUid())) {
                throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401011);
            }

            /*
             * 思路：1、设置坐席时，先判断该用户是否被注册且注册人数是否超出，如果注册人数未超出时，则未被注册的用户走注册逻辑，超出注册人数则走绑定逻辑，
             *          已被注册则直接走绑定逻辑
             *       2、取消坐席时走解绑逻辑
             */
            if (staff == 1) {
                Map<String, Object> param = new HashMap<>(16);
                param.put("corpid", corpid);
                param.put("staff", 1);
                param.put("del", DelEnum.NORMAL.getDel());
                // 正在使用搜客的人数
                int count = searchCustomerUserModel.getEntitysCount(param);
                int allowCount = soukeCompanyEntity.getUseCount();

                if (count >= allowCount) {
                    throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401001);
                }
                // 注册的人数
                int registerCount = searchCustomerUserModel.getRegisterCount(param);
                if (entity == null) {
                    entity = new SearchCustomerUserEntity();
                    entity.setCorpid(corpid);
                    entity.setUserId(allowUserId);

                    if (registerCount < allowCount) {
                        // 注册用户
                        SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(uid);
                        // 为该账号注册搜客
                        searchCustomerDTO.setParent_user(soukeCompanyEntity.getUid());
                        searchCustomerDTO.setUsername(allowUserEntity.getName());
                        // 角色为子账号（不可改变）
                        searchCustomerDTO.setRole("subaccount");
                        JSONObject data = sendRegister(searchCustomerDTO);
                        LOG.info("=====设置坐席时注册=======" + data);
                        // API第三方uid已存在
                        if (data != null && (int) data.get("error_code") == 6101) {
                            // 解决搜客与crm数据库表中数据不一致问题（产生原因：调用搜客接口出现问题，但他们那边已执行操作，我们这边未执行）
                            JSONObject jsonObject = info(searchCustomerDTO);
                            JSONObject obj = (JSONObject) jsonObject.get("data");
                            String clueUserId = (String) obj.get("user_id");
                            entity.setClueUserId(clueUserId);
                            entity.setAdmin(0);
                            entity.setStaff(staff);
                            entity.setIsBind(1);
                            entity.setDel(0);
                            searchCustomerUserModel.insert(entity);
                            searchCustomerMsgVO.setCode(ErrorCodeEnum.API_SUCCESS.getCode());
                            searchCustomerMsgVO.setMsg(ErrorCodeEnum.API_SUCCESS.getMsg());
                            return searchCustomerMsgVO;
                        }

                        // 如果注册提示子账户已满需提示(子账户超过上限)
                        if (data != null && (int) data.get("error_code") == 6015) {
                            searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401001.getCode());
                            searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401001.getMsg());
                            return searchCustomerMsgVO;
                        }
                        if (data == null || (int) data.get("error_code") != 0) {
                            searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401005.getCode());
                            searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401005.getMsg());
                            return searchCustomerMsgVO;
                        }
                        JSONObject jsonObject = info(searchCustomerDTO);
                        JSONObject obj = (JSONObject) jsonObject.get("data");
                        String clueUserId = (String) obj.get("user_id");
                        entity.setClueUserId(clueUserId);
                        entity.setIsBind(1);
                    } else {
                        changeBind(corpid, uid, entity);
                    }
                    entity.setAdmin(0);
                    entity.setStaff(staff);
                    entity.setDel(0);
                    searchCustomerUserModel.insert(entity);
                } else if (entity.getStaff() == 0) {
                    if (StringUtil.isEmpty(entity.getClueUserId())) {
                        /*
                         * 1、更换主账户后未进行注册的账号，例如：主账户A->B->A，那么B未注册但entity不为空，如果能注册则B走注册逻辑
                         * 2、账号P设置坐席后，又取消坐席，再次设置坐席时的情况，如果能注册则走注册逻辑
                         */
                        if (registerCount < allowCount) {
                            // 注册用户
                            SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(uid);
                            // 为该账号注册搜客
                            searchCustomerDTO.setParent_user(soukeCompanyEntity.getUid());
                            searchCustomerDTO.setUsername(allowUserEntity.getName());
                            // 角色为子账号（不可改变）
                            searchCustomerDTO.setRole("subaccount");
                            JSONObject data = sendRegister(searchCustomerDTO);
                            LOG.info("=====设置坐席时注册=======" + data);
                            // API第三方uid已存在
                            if (data != null && (int) data.get("error_code") == 6101) {
                                // 解决搜客与crm数据库表中数据不一致问题（产生原因：调用搜客接口出现问题，但他们那边已执行操作，我们这边未执行）
                                JSONObject jsonObject = info(searchCustomerDTO);
                                JSONObject obj = (JSONObject) jsonObject.get("data");
                                String clueUserId = (String) obj.get("user_id");
                                entity.setClueUserId(clueUserId);
                                entity.setStaff(staff);
                                entity.setIsBind(1);
                                entity.setDel(0);
                                searchCustomerUserModel.update(entity);
                                searchCustomerMsgVO.setCode(ErrorCodeEnum.API_SUCCESS.getCode());
                                searchCustomerMsgVO.setMsg(ErrorCodeEnum.API_SUCCESS.getMsg());
                                return searchCustomerMsgVO;
                            }

                            // 如果注册提示子账户已满需提示(子账户超过上限)
                            if (data != null && (int) data.get("error_code") == 6015) {
                                searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401001.getCode());
                                searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401001.getMsg());
                                return searchCustomerMsgVO;
                            }
                            if (data == null || (int) data.get("error_code") != 0) {
                                searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401005.getCode());
                                searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401005.getMsg());
                                return searchCustomerMsgVO;
                            }
                            JSONObject jsonObject = info(searchCustomerDTO);
                            JSONObject obj = (JSONObject) jsonObject.get("data");
                            String clueUserId = (String) obj.get("user_id");
                            entity.setClueUserId(clueUserId);
                            entity.setIsBind(1);
                        }else {
                            changeBind(corpid, uid, entity);
                        }
                    } else {
                        // 如果已有clue_user_id与entity绑定，则改变staff的状态
                        SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(uid);
                        searchCustomerDTO.setUser_id(entity.getClueUserId());
                        JSONObject data = bind(searchCustomerDTO);
                        LOG.info("=====设置坐席时绑定=======" + data);
                        if (data == null || (int) data.get("error_code") != 0) {
                            searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401005.getCode());
                            searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401005.getMsg());
                            return searchCustomerMsgVO;
                        }
                    }

                    entity.setStaff(staff);
                    // 需要设置del=0原因：存在账号之前是离职后又复职的情况
                    entity.setDel(0);
                    searchCustomerUserModel.update(entity);
                }
            } else if (entity == null && staff == 0) {
                throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401005);
            } else if (staff == 0) {
                // 解绑操作
                SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(uid);
                searchCustomerDTO.setUser_id(entity.getClueUserId());
                JSONObject data = unbind(searchCustomerDTO);
                LOG.info("=====取消坐席时解绑=======" + data);
                if (data == null || (int) data.get("error_code") != 0) {
                    searchCustomerMsgVO.setCode(SearchCustomerErrorCodeEnum.API_ERROR_401005.getCode());
                    searchCustomerMsgVO.setMsg(SearchCustomerErrorCodeEnum.API_ERROR_401005.getMsg());
                    return searchCustomerMsgVO;
                }
                entity.setStaff(staff);
                entity.setToken("");
                searchCustomerUserModel.update(entity);
            }
        }catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("修改搜客坐席错误：" , e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018, "修改搜客坐席错误");
        }

        searchCustomerMsgVO.setCode(ErrorCodeEnum.API_SUCCESS.getCode());
        searchCustomerMsgVO.setMsg(ErrorCodeEnum.API_SUCCESS.getMsg());
        return searchCustomerMsgVO;
    }

    /**
     * 注册人数已满，走绑定的逻辑
     * @param corpid
     * @param uid
     * @param entity
     * @author 石安
     * @date 2019-10-29
     */
    private void changeBind(String corpid, String uid, SearchCustomerUserEntity entity) throws XbbException{
        try {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("staff", 0);
            List<SearchCustomerUserEntity> entityList = searchCustomerUserModel.getUnBindInfo(param);
            if (entityList.size() > 0) {
                SearchCustomerUserEntity unBindEntity = entityList.get(0);
                String clueUserId = unBindEntity.getClueUserId();
                SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(uid);
                searchCustomerDTO.setUser_id(clueUserId);
                JSONObject data = bind(searchCustomerDTO);
                LOG.info("=====设置坐席时绑定=======" + data);
                if (data == null || (int) data.get("error_code") != 0) {
                    throw new XbbException(SearchCustomerErrorCodeEnum.API_ERROR_401005);
                }
                entity.setClueUserId(clueUserId);
                entity.setIsBind(0);
                unBindEntity.setClueUserId("");
                searchCustomerUserModel.update(unBindEntity);
            }
        } catch (Exception e) {
            LOG.error("=====设置坐席时绑定error=======" + e.getMessage());
            throw e;
        }
    }

    @Override
    public SearchCustomerVO search(@Valid SearchEnterpriseDTO searchEnterpriseDTO) throws XbbException {
        SearchCustomerVO searchCustomerVO = new SearchCustomerVO();
        JSONObject jsonObject;
        try {
            String keyword = searchEnterpriseDTO.getKeyword();
            Integer offset = searchEnterpriseDTO.getOffset();
            if (offset == null){
                offset = 1;
            }

            String url = String.format(SoukeUrlConstant.SEARCH_ENTERPRISE_URL, keyword, offset);

            jsonObject = searchCustomerHelp.httpExchange(url, "", HttpMethod.GET, SoukeMealEnum.BUSINESS);
            searchCustomerVO = JSONObject.toJavaObject(jsonObject ,SearchCustomerVO.class);
        } catch (XbbException e) {
            LOG.error("模糊查询失败：" + e.getMessage());
        }
        return searchCustomerVO;
    }

    @Override
    public SearchCustomerVO baseInfo(@Valid SearchEnterpriseDTO searchEnterpriseDTO) throws XbbException {
        SearchCustomerVO searchCustomerVO = new SearchCustomerVO();
        JSONObject information;
        JSONObject report;
        JSONObject data = new JSONObject();
        try {
            String keyword = searchEnterpriseDTO.getKeyword();
            String url = String.format(SoukeUrlConstant.BASEINFO_ENTERPRISE_URL, keyword);

            // 发送get请求调用企业基本信息V3接口(获取客户简称与地址)
            information = searchCustomerHelp.httpExchange(url, "", HttpMethod.GET, SoukeMealEnum.BUSINESS);
            if (Objects.isNull(information)) {
                return searchCustomerVO;
            }
            JSONObject informationData = information.getJSONObject(StringConstant.JSON_DATA);

            // 发送get请求发送企业年报接口(获取客户电话)
            url = String.format(SoukeUrlConstant.ANNUALLIST_ENTERPRISE_URL, keyword);
            report = searchCustomerHelp.httpExchange(url, "", HttpMethod.GET, SoukeMealEnum.BUSINESS);
            if (Objects.isNull(report)) {
                return searchCustomerVO;
            }
            JSONArray reportDataList = report.getJSONArray(StringConstant.JSON_DATA);

            String oploc = informationData.getString("OPLOC");
            String tel = "";
            if (reportDataList.size() > 0) {
                JSONObject baseInfo = reportDataList.getJSONObject(0).getJSONObject("baseInfo");
                tel = (String) baseInfo.get("tel");
            }
            data.put(CustomerManagementEnum.NAME.getAttr(), keyword);
            data.put(CustomerManagementEnum.NAME_SHORT.getAttr(), informationData.getString("LEGALPERSON"));
            JSONArray telArray = new JSONArray();
            JSONObject phone = new JSONObject();
            phone.put("text_1", "1");
            phone.put("text_2", tel);
            telArray.add(phone);
            data.put(CustomerManagementEnum.PHONE.getAttr(), telArray);
            data.put(CustomerManagementEnum.ADDRESS.getAttr(), searchCustomerHelp.changeAddress(oploc));

            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(searchEnterpriseDTO.getFormId(), searchEnterpriseDTO.getCorpid());
            List<FieldAttrEntity> fieldList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldAttrEntity : fieldList) {
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType());
                DefaultAttrPoJo defaultAttr = fieldAttrEntity.getDefaultAttr();
                BusinessFieldPojo businessFieldPojo = defaultAttr.getBusinessMatchAttr();
                if (Objects.nonNull(businessFieldPojo)) {
                    String attr = businessFieldPojo.getAttr();
                    BusinessSearchEnum businessSearchEnum = BusinessSearchEnum.getByCode(businessFieldPojo.getCode());
                    if (businessSearchEnum == null || StringUtils.isEmpty(attr) || fieldTypeEnum == null) {
                        continue;
                    }
                    if (Objects.equals(businessFieldPojo.getSource(), INFORMATION)) {
                        switch (fieldTypeEnum) {
                            case TEXT:
                                if (Objects.equals(attr, BusinessSearchEnum.REGISTER_FUNDS.getAttr())) {
                                    String[] split = attr.split("&&");
                                    BigDecimal regCap = informationData.getBigDecimal(split[0]);
                                    if (regCap != null) {
                                        String capUnit = informationData.getString(split[1]);
                                        data.put(fieldAttrEntity.getAttr(), regCap.toString() + capUnit);
                                    }
                                } else {
                                    data.put(fieldAttrEntity.getAttr(), informationData.getString(attr));
                                }
                                break;
                            case NUM:
                                data.put(fieldAttrEntity.getAttr(), informationData.getInteger(attr));
                                break;
                            case COMBO:
                                // 下拉框转换成规范格式
                                JSONObject combo = new JSONObject();
                                if (Objects.equals(businessSearchEnum.getFieldType(), FieldTypeEnum.TEXT.getType())) {
                                    String comboStr = informationData.getString(attr);
                                    if (Objects.equals(attr, BusinessSearchEnum.REGISTER_FUNDS.getAttr())) {
                                        String[] split = attr.split("&&");
                                        BigDecimal regCap = informationData.getBigDecimal(split[0]);
                                        String capUnit = informationData.getString(split[1]);
                                        comboStr = regCap.toString() + capUnit;
                                    }
                                    combo.put("text", comboStr);
                                    combo.put("value", comboStr);
                                } else if (Objects.equals(businessSearchEnum.getFieldType(), FieldTypeEnum.NUM.getType())) {
                                    combo.put("text", informationData.getInteger(attr));
                                    combo.put("value", informationData.getInteger(attr));
                                }
                                data.put(fieldAttrEntity.getAttr(), combo);
                                break;
                            case DATETIME:
                                String dateString = informationData.getString(attr).replaceAll("Z", " UTC");
                                int date = DateUtil.getInt(dateString, DateTimeUtil.SDF_Z);
                                data.put(fieldAttrEntity.getAttr(), date);
                                break;
                            case ADDRESS:
                                // 地址转换成规范格式
                                JSONObject addr = searchCustomerHelp.changeAddress(informationData.getString(attr));
                                data.put(fieldAttrEntity.getAttr(), addr);
                                break;
                            case SUB_FORM:
                                JSONArray jsonArray = informationData.getJSONArray(attr);
                                List<JSONObject> subArray = new ArrayList<>();
                                SubFormPoJo subForm = fieldAttrEntity.getSubForm();
                                List<? extends FieldAttrEntity> items = subForm.getItems();
                                for (Object obj : jsonArray) {
                                    JSONObject subData = (JSONObject) obj;
                                    JSONObject subObj = new JSONObject();
                                    for (FieldAttrEntity item : items) {
                                        DefaultAttrPoJo subDefault = item.getDefaultAttr();
                                        BusinessFieldPojo subBusinessAttr = subDefault.getBusinessMatchAttr();
                                        if (Objects.nonNull(subBusinessAttr)) {
                                            if (Objects.equals(item.getFieldType(), FieldTypeEnum.COMBO.getType())) {
                                                // 下拉框转换成规范格式
                                                JSONObject subCombo = new JSONObject();
                                                subCombo.put("text", subData.getString(subBusinessAttr.getAttr()));
                                                subCombo.put("value", subData.getString(subBusinessAttr.getAttr()));
                                                subObj.put(item.getAttr(), subCombo);
                                            }
                                            subObj.put(item.getAttr(),subData.getString(subBusinessAttr.getAttr()));
                                        }
                                    }
                                    if (subObj.size() > 0) {
                                        subArray.add(subObj);
                                    }
                                }
                                data.put(fieldAttrEntity.getAttr(), subArray);
                                break;
                            default:
                                data.put(fieldAttrEntity.getAttr(), informationData.getString(attr));
                                break;
                        }
                    } else if (Objects.equals(businessFieldPojo.getSource(), REPORT) && CollectionsUtil.isNotEmpty(reportDataList)) {
                        JSONObject reportData = reportDataList.getJSONObject(0);
                        JSONObject baseInfo = reportData.getJSONObject("baseInfo");
                        if (Objects.equals(fieldTypeEnum, FieldTypeEnum.CONTACT_NUMBER)) {
                            JSONArray jsonArray = new JSONArray();
                            JSONObject obj = new JSONObject();
                            obj.put("text_1", "1");
                            obj.put("text_2", baseInfo.getString(attr));
                            jsonArray.add(obj);
                            data.put(fieldAttrEntity.getAttr(), jsonArray);
                        } else {
                            data.put(fieldAttrEntity.getAttr(), baseInfo.getString(attr));
                        }
                    }
                }
            }
            data.put(CustomerManagementEnum.CLUE_COMPANY_ID.getAttr(), searchEnterpriseDTO.getPid());

            searchCustomerVO.setData(data);
        } catch (XbbException e) {
            LOG.error("企业信息获取失败：" + e.getMessage());
        }
        return searchCustomerVO;
    }

    @Override
    public JSONObject haveEnterpriseInfo(String keyword) throws XbbException {
        String url = String.format(SoukeUrlConstant.BASEINFO_ENTERPRISE_URL, keyword);
        // 发送get请求调用企业基本信息V3接口
        JSONObject jsonObject = searchCustomerHelp.httpExchange(url, "", HttpMethod.GET, SoukeMealEnum.BUSINESS);
        if (Objects.isNull(jsonObject)) {
            return null;
        }
        return (JSONObject) jsonObject.get("data");
    }

    @Override
    public void removeSoukePosition(String corpId, String userId) throws XbbException {
        SearchCustomerCompanyEntity soukeCompanyEntity = searchCustomerCompanyModel.getByCorpid(corpId, SoukeMealEnum.SOUKE.getType());
        SearchCustomerUserEntity soukeUserEntity = searchCustomerUserModel.getByKey(userId, corpId);
        /*
         * 子账户M离职：M做解绑操作，M的del=1，staff=0，isBind=0
         * 主账户P离职：寻找所有坐席的list，默认取第一个（Q用户）为主账户的代替品，Q做解绑操作，Q的admin=1，P与Q的clue_user_id互换，P的admin=0，staff=0，isBind=0,del=1;
         */
        String uid = corpId + userId;
        if (soukeUserEntity != null && soukeUserEntity.getStaff() == 1) {
            LOG.info("removeSoukePosition ----  员工离职取消搜客坐席");
            // 对离职的员工是搜客坐席进行处理
            if (!Objects.equals(uid, soukeCompanyEntity.getUid()) && !Objects.equals(userId, soukeCompanyEntity.getUserId())) {
                // 对子账户做解绑逻辑
                SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(uid);
                searchCustomerDTO.setUser_id(soukeUserEntity.getClueUserId());
                unbind(searchCustomerDTO);
                soukeUserEntity.setStaff(0);
                soukeUserEntity.setToken("");
                soukeUserEntity.setDel(1);
                searchCustomerUserModel.update(soukeUserEntity);
            } else if (Objects.equals(userId, soukeCompanyEntity.getUserId())) {
                soukeCompanyEntity.setUserId("");
                soukeCompanyEntity.setUsername("");
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpId);
                param.put("admin", 0);
                param.put("staff", 1);
                param.put("del", DelEnum.NORMAL.getDel());
                List<SearchCustomerUserEntity> entityList = searchCustomerUserModel.findEntitys(param);
                Optional<SearchCustomerUserEntity> first = entityList.stream().filter(s -> !userId.equals(s.getUserId())).findFirst();
                if (first.isPresent()) {
                    SearchCustomerUserEntity entity = first.get();
                    UserEntity userEntity = userModel.getByKey(entity.getUserId(), entity.getCorpid());
                    String simpleClueUserId = entity.getClueUserId();
                    String adminClueUserId = soukeUserEntity.getClueUserId();
                    SearchCustomerDTO searchCustomerDTO = new SearchCustomerDTO(entity.getCorpid() + entity.getUserId());
                    searchCustomerDTO.setUser_id(simpleClueUserId);
                    unbind(searchCustomerDTO);
                    entity.setAdmin(1);
                    entity.setClueUserId(adminClueUserId);
                    searchCustomerUserModel.update(entity);

                    soukeUserEntity.setClueUserId(simpleClueUserId);

                    soukeCompanyEntity.setUserId(entity.getUserId());
                    soukeCompanyEntity.setUsername(userEntity.getName());
                }
                soukeUserEntity.setAdmin(0);
                soukeUserEntity.setStaff(0);
                soukeUserEntity.setDel(1);
                searchCustomerUserModel.update(soukeUserEntity);
                searchCustomerCompanyModel.update(soukeCompanyEntity);
            }

        }

    }

    @Override
    public String handelDetailClue(PaasFormDataEntityExt paasFormDataEntityExt) {
        String corpid = paasFormDataEntityExt.getCorpid();
        boolean flag = false;
        SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.SOUKE.getType());
        // 销客已不提供工商查询功能，这部分逻辑要去掉 2022-1-7 by hongxiao
//        SearchCustomerCompanyEntity businessEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
//        if (businessEntity != null && businessEntity.getExtraExpiry() > DateUtil.getInt()) {
//            flag = true;
//        }
        if (soukeEntity != null && soukeEntity.getExtraExpiry() > DateUtil.getInt()) {
            flag = true;
        }
        if (!flag) {
            return null;
        }
        try {
            JSONObject jsonObject = haveEnterpriseInfo(paasFormDataEntityExt.getData().getString(CustomerManagementEnum.NAME.getAttr()));
            if (jsonObject == null) {
                return null;
            }else {
                String pid = jsonObject.getString("PID");
                return pid;
            }
        } catch (XbbException e) {
            LOG.info("跳转栗子详情获取企业基本信息", e.getMsg());
        }
        return null;
    }

    @Override
    public JumpClueDetailVO getClueDetail(@Valid SearchEnterpriseDTO searchEnterpriseDTO) throws XbbException{
        JumpClueDetailVO jumpClueDetailVO = new JumpClueDetailVO();
        String corpid = searchEnterpriseDTO.getCorpid();
        String userId = searchEnterpriseDTO.getUserId();
        int type = ClueDetailJoinEnum.SIMPLE_BUSINESS.getType();
        String uid = "";
        SearchCustomerCompanyEntity soukeEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.SOUKE.getType());
        SearchCustomerCompanyEntity businessEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
        SearchCustomerUserEntity searchCustomerUserEntity = searchCustomerUserModel.getByKey(userId, corpid);

        /**
         * 登录的优先级：工商账号<游客账号<搜客账号
         */
        //搜客或工商查询的试用
        if (Objects.nonNull(businessEntity) && businessEntity.getExtraExpiry() > DateUtil.getInt()) {
            type = ClueDetailJoinEnum.SIMPLE_BUSINESS.getType();
            if (businessEntity.getExtraExpiry() - DateUtil.getInt() < RedisTimeConstant.LONG_DURATION * 4) {
                uid = corpid + ValueAddedTypeEnum.BUSINESS_SEARCH.getType();
            } else {
                // 工商账号uid为corpid
                uid = corpid;
            }
        }

        if (Objects.nonNull(soukeEntity) && soukeEntity.getExtraExpiry() > DateUtil.getInt()) {
            if (soukeEntity.getExtraExpiry() - DateUtil.getInt() < RedisTimeConstant.LONG_DURATION * 4) {
                type = ClueDetailJoinEnum.NORMAL_SOUKE.getType();
                uid = corpid + ValueAddedTypeEnum.SEARCH_CUSTOMER.getType();
            }else if (searchCustomerUserEntity == null || searchCustomerUserEntity.getStaff() == 0) {
                // 采用游客登录方式：使用主账户uid，guest=1注册游客账号获取user_token登录
                type = ClueDetailJoinEnum.TOURIST_SOUKE.getType();
                uid = soukeEntity.getUid();
            }else if (searchCustomerUserEntity.getStaff() == 1) {
                // 正常的账号登录,uid为corpid+userId
                type = ClueDetailJoinEnum.NORMAL_SOUKE.getType();
                uid = corpid + userId;
                if (Objects.equals(userId, soukeEntity.getUserId())){
                   uid = soukeEntity.getUid();
                }
            }
        }
        jumpClueDetailVO.setType(type);
        jumpClueDetailVO.setUid(uid);
        return jumpClueDetailVO;
    }

}
